home *** CD-ROM | disk | FTP | other *** search
/ Aminet 20 / Aminet 20 (1997)(GTI - Schatztruhe)[!][Aug 1997].iso / Aminet / hard / drivr / vbak2091.lha / vb2091.c < prev    next >
C/C++ Source or Header  |  1997-06-25  |  9KB  |  283 lines

  1. /* vb2091 0.3 (c) in 1994 by Volker Barthelmann */
  2.  
  3. #include <string.h>
  4.  
  5. #include <exec/execbase.h>
  6. #include <exec/memory.h>
  7. #include <exec/io.h>
  8. #include <exec/semaphores.h>
  9. #include <devices/trackdisk.h>
  10. #include <devices/timer.h>
  11. #include <dos/dosextens.h>
  12. #include <dos/filehandler.h>
  13. #include <dos/dostags.h>
  14.  
  15. #include <clib/exec_protos.h>
  16. #include <clib/alib_protos.h>
  17. #include <clib/dos_protos.h>
  18.  
  19. #define MAXUNIT 8
  20.  
  21. char zahl[]="0123456789";
  22. struct IOStdReq *IO[MAXUNIT];
  23. struct SignalSemaphore *ss;
  24.  
  25. #define DEV_BEGINIO (-30)
  26.  
  27. #define min(a,b)    ((a) < (b) ? (a) : (b))
  28.  
  29. #define STAY   1
  30. #define BROKEN 2
  31. #define SINGLEF 4
  32. #define NOCACHE 8
  33. #define NOWRITE 16
  34.  
  35. void (*oldbeginio)(__reg("a1") struct IOStdReq *, __reg("a6") struct Device *);
  36. void (*oldarray[8])();
  37.  
  38. void    *Unit[MAXUNIT];
  39.  
  40. int SIZE=262144,msize,flags,UnitNr,unitmask;
  41. int MAXN=16,MIN1BUF=131072,MIN2BUF=65536;
  42. char *buffer;
  43.  
  44. struct MsgPort *iosink[MAXUNIT];
  45.  
  46.  
  47. void mybeginio(__reg("a1") struct IOStdReq *req,__reg("a6") struct Device *dev)
  48. {
  49.     struct MsgPort *port;
  50.     struct IOStdReq *mreq;
  51.     unsigned int actual,data,offset,length,lactual,ldata,flag,msize;
  52.     int un=-1;
  53.  
  54.     geta4();
  55.  
  56.     mreq=req;
  57.     ObtainSemaphore(ss);
  58.  
  59.     for(flag=0;flag<MAXUNIT;flag++)
  60.         if(req->io_Unit==Unit[flag])
  61.             un=flag;
  62.     if(un==-1) goto old;
  63.  
  64. /*    oldbeginio=oldarray[un];*/
  65.  
  66.     if((req->io_Command & 0xFF) == CMD_READ){
  67.         if((flags & BROKEN)==0 && (unsigned long) req->io_Data<16777216)
  68.             goto old;
  69.         port=(struct MsgPort *)CreatePort(NULL,0);
  70.         IO[un]->io_Message.mn_ReplyPort=port;
  71.         actual=0;
  72.         length=mreq->io_Length;
  73.         if(length>MIN2BUF*MAXN){
  74.             msize=min((length+MAXN-1)/MAXN,SIZE/2);
  75.         }else{
  76.             if(length<MIN1BUF) msize=min(length,SIZE/2);
  77.                           else msize=min(MIN2BUF,SIZE/2);
  78.         }
  79.         if(msize>=512) msize&=0xfffffe00;
  80.         offset=mreq->io_Offset;
  81.         data=(unsigned int) mreq->io_Data;
  82.         lactual=flag=0;ldata=data;
  83.         if(flags&NOCACHE) CacheControl(0,CACRF_EnableD);
  84.         do{
  85.             IO[un]->io_Offset=offset;
  86.             if(flags&SINGLEF){
  87.                 IO[un]->io_Length=min(SIZE,length);
  88.                 IO[un]->io_Data=buffer;
  89.             }else{
  90.                 IO[un]->io_Length=min(msize,length);
  91.                 if(flag==0) IO[un]->io_Data=buffer; else
  92.                   IO[un]->io_Data=buffer+SIZE/2;
  93.             }
  94.             IO[un]->io_Command=CMD_READ;
  95.             oldbeginio(req=IO[un],IO[un]->io_Device);
  96.             if((flags&SINGLEF)==0){
  97.                 if(flag!=0) CopyMem(buffer,(APTR) ldata,lactual);
  98.                 else CopyMem(buffer+SIZE/2,(APTR) ldata,lactual);
  99.             }
  100.             WaitIO((struct IORequest *) IO[un]);
  101.             actual+=IO[un]->io_Actual;lactual=IO[un]->io_Actual;
  102.             ldata=data;data+=IO[un]->io_Actual;
  103.             offset+=IO[un]->io_Actual;
  104.             length-=IO[un]->io_Actual;
  105.             flag=1-flag;
  106.             if(flags&SINGLEF) CopyMem(buffer,(APTR) ldata,lactual);
  107.  
  108.         }while(length>0 && IO[un]->io_Actual>=IO[un]->io_Length);
  109.         if((flags&SINGLEF)==0){
  110.             if(flag!=0) CopyMem(buffer,(APTR) ldata,lactual);
  111.             else CopyMem(buffer+SIZE/2,(APTR) ldata,lactual);
  112.         }
  113.         if(flags&NOCACHE) CacheControl(0xffffffff,CACRF_EnableD);
  114.         mreq->io_Actual=actual;
  115.         mreq->io_Error=IO[un]->io_Error;
  116.         DeletePort(port);
  117.         if(!(mreq->io_Flags & IOF_QUICK))
  118.             ReplyMsg(&mreq->io_Message);
  119.         ReleaseSemaphore(ss);
  120.         return;
  121.     }
  122.     if((req->io_Command & 0xFF) == CMD_WRITE){
  123.         if(flags&NOWRITE) goto old;
  124.         if((flags & BROKEN)==0 && (unsigned long) req->io_Data<16777216)
  125.             goto old;
  126.         port=(struct MsgPort *)CreatePort(NULL,0);
  127.         IO[un]->io_Message.mn_ReplyPort=port;
  128.         actual=0;
  129.         length=mreq->io_Length;
  130.         offset=mreq->io_Offset;
  131.         data=(unsigned int) mreq->io_Data;
  132.         if(flags&NOCACHE) CacheControl(0,CACRF_EnableD);
  133.         do{
  134.             if(SIZE>=length) IO[un]->io_Length=length; else
  135.               IO[un]->io_Length=SIZE;
  136.             CopyMem((APTR) data,buffer,IO[un]->io_Length);
  137.             IO[un]->io_Offset=offset;
  138.             IO[un]->io_Data=buffer;
  139.             IO[un]->io_Command=CMD_WRITE;
  140.             oldbeginio(req=IO[un],IO[un]->io_Device);
  141.             WaitIO((struct IORequest *) IO[un]);
  142.             actual+=IO[un]->io_Actual;
  143.             data+=IO[un]->io_Actual;
  144.             offset+=IO[un]->io_Actual;
  145.             length-=IO[un]->io_Actual;
  146.         }while(length>0 && IO[un]->io_Actual>=IO[un]->io_Length);
  147.         if(flags&NOCACHE) CacheControl(0xffffffff,CACRF_EnableD);
  148.         mreq->io_Actual=actual;
  149.         mreq->io_Error=IO[un]->io_Error;
  150.         DeletePort(port);
  151.         if(!(mreq->io_Flags & IOF_QUICK))
  152.             ReplyMsg(&mreq->io_Message);
  153.         ReleaseSemaphore(ss);
  154.         return;
  155.     }
  156. old:
  157.     oldbeginio(req,dev);
  158.     ReleaseSemaphore(ss);
  159. }
  160.  
  161.  
  162. int
  163. main(int argc, char *argv[])
  164. {
  165.     long            tmp;
  166.     BPTR            op;
  167.     int             devopen,i;
  168.     char *Device="2nd.scsi.device",*p;
  169.  
  170.     tmp = 0;
  171.     devopen = 0;
  172.     op=Output();
  173.     for(i=1; i<argc; i++){
  174.         /*printf("Arg: %d  %s: ",i,argv[i]);*/
  175.         if(!strcmp("BUFSIZE",argv[i])){
  176.             SIZE=atoi(argv[++i])*1024;continue;}
  177.         if(!strcmp("MIN1BUF",argv[i])){
  178.             MIN1BUF=atoi(argv[++i])*1024;continue;}
  179.         if(!strcmp("MIN2BUF",argv[i])){
  180.             MIN2BUF=atoi(argv[++i])*1024;continue;}
  181.         if(!strcmp("MAXN",argv[i])){
  182.             MAXN=atoi(argv[++i]);continue;}
  183.         if(!strcmp("DEVICE",argv[i])){
  184.             Device=argv[++i];continue;}
  185.         if(!strcmp("UNIT",argv[i])){
  186.             p=argv[++i];
  187.             while(*p!=0){
  188.                 if(*p<'0'||*p>'7') {Write(op,"You can only use unit 0..7!!\n",29L);exit(0);}
  189.                 unitmask|=1<<(*p-'0');
  190.                 p++;
  191.             }
  192.             continue;}
  193.         if(!strcmp("BROKEN",argv[i])){
  194.             flags|=BROKEN;continue;}
  195.         if(!strcmp("SINGLE",argv[i])){
  196.             flags|=SINGLEF;continue;}
  197.         if(!strcmp("NOCACHE",argv[i])){
  198.             flags|=NOCACHE;continue;}
  199.         if(!strcmp("NOWRITE",argv[i])){
  200.             flags|=NOWRITE;continue;}
  201.         Write(op,"Wrong argument: ",16L);
  202.         Write(op,argv[i],strlen(argv[i]));
  203.         Write(op,"\nPLEASE READ THE MANUAL !!\n",27L);
  204.         exit(0);
  205.     }
  206.  
  207.     Write(op,"vb2091 V0.3 (c) in 1994,1996 by Volker Barthelmann\n",52L);
  208.     /*printf("Flags: %d  SIZE: %d  Device: %s\n",flags,SIZE,Device);*/
  209.     /*printf("unitmask: %d\n",unitmask);*/
  210.     for(i=0;i<MAXUNIT;i++){
  211.         if((unitmask&(1<<i))==0) continue;
  212.         iosink[i] = (struct MsgPort *)CreatePort(NULL, 0);
  213.         IO[i] = (struct IOStdReq *) CreateExtIO(iosink[i], sizeof (*IO[0]));
  214.         tmp = OpenDevice(Device, i, (struct IORequest *) IO[i], 0);
  215.  
  216.         if (tmp) {
  217.             Write(op,"Unable to open ",15L);
  218.             Write(op,Device,strlen(Device));
  219.             Write(op," Unit ",6L);Write(op,&(zahl[i]),1L);
  220.             Write(op,"\n",1L);
  221. /*            if(IO[i])DeleteExtIO((struct IORequest *) IO[i]);
  222.             if(iosink[i]) DeletePort(iosink[i]);  */
  223.             IO[i]=0;
  224.             continue;
  225.         } else{
  226.             Write(op,"Opened ",7L);
  227.             Write(op,Device,strlen(Device));
  228.             Write(op," Unit ",6L);Write(op,&(zahl[i]),1L);
  229.             Write(op,"\n",1L);
  230.  
  231.             devopen = 1;
  232.             /*printf("Opened %s unit %d\n",Device,i);*/
  233.  
  234.             SumLibrary((struct Library *) IO[i]->io_Device);
  235. /*            oldarray[i] = (void (* )()) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);*/
  236.             if(!oldbeginio) oldbeginio = (void (* )()) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) &mybeginio);
  237.             Unit[i]=IO[i]->io_Unit;
  238.         }
  239.     }
  240.     ss = (struct SignalSemaphore *)AllocMem(sizeof (struct SignalSemaphore), MEMF_PUBLIC);
  241.     if (!ss)
  242.         goto quit;
  243.     InitSemaphore(ss);
  244.  
  245.     if(flags&BROKEN)
  246.         buffer=(char *)AllocMem(SIZE,MEMF_24BITDMA|MEMF_FAST|MEMF_PUBLIC);
  247.     else
  248.         buffer=(char *)AllocMem(SIZE,MEMF_24BITDMA|MEMF_PUBLIC);
  249.  
  250.     if(buffer==0) {Write(op,"Cannot allocate buffer!!\n",25L);goto quit;}
  251.  
  252.  
  253.     if(devopen) Wait(SIGBREAKF_CTRL_C);
  254.  
  255. quit:
  256.  
  257.     ObtainSemaphore(ss);
  258.     for(i=MAXUNIT-1;i>=0;i--){
  259. /*        if(IO[i]) printf("Restoring Unit %d\n",i);*/
  260. /*        if(IO[i]) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) oldarray[i]);*/
  261.         if(IO[i]) SetFunction((struct Library *) IO[i]->io_Device, DEV_BEGINIO, (APTR) oldbeginio);
  262.     }
  263.     ReleaseSemaphore(ss);
  264.  
  265.  
  266.     if(buffer)
  267.         FreeMem(buffer, SIZE);
  268.     if (ss)
  269.         FreeMem(ss, sizeof (struct SignalSemaphore));
  270.     for(i=0;i<MAXUNIT;i++){
  271.         if (devopen) {
  272.             if(IO[i]) CloseDevice((struct IORequest *) IO[i]);
  273.         }
  274.         if (IO[i])
  275.             DeleteExtIO((struct IORequest *) IO[i]);
  276.         if (iosink[i])
  277.             DeletePort(iosink[i]);
  278.     }
  279.  
  280.     return 0;
  281. }
  282.  
  283.